#define VAR_PAGE_GLOBALS
#include "page.h"
#include <stdio.h>
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include "esp_wifi.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "esp_event.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_heap_caps.h"
#include "esp_log.h"
#include "esp_spiffs.h"
#include "scan.h"
#include "button.h"
#include "led_strip.h"
#include "driver/rmt.h"
#include "mainPage.h"
#include "led.h"
#include "mp3Page.h"
#include "smart_config.h"
#include "weather.h"
#include "calendar.h"

static lv_obj_t *spinner;
static lv_obj_t *label2;
static const char *TAG = "page";
/**************************************************************/
#include<stdio.h>
#include<stdlib.h>
#define MaxSize 5


typedef struct
{
    page_t Data[MaxSize];   // 存储元素的数组
    int topIdx;       //栈顶指针
} SeqStack;

SeqStack pageStack;

// 将元素推入栈中
int push_page(page_t e)
{
    // 栈已满
    if (pageStack.topIdx == MaxSize - 1)
    {
        return 0;
    }
    // 加入栈中
    pageStack.Data[pageStack.topIdx++] = e;
    // 返回自身
    return e;
}
// 移除栈顶元素
page_t pop_page()
{
    // 栈空
    if (pageStack.topIdx == 0)
    {
        //返回失败
        return 0;
    }
    // 打印并返回栈
    return pageStack.Data[--pageStack.topIdx];
}

// 获取栈顶元素 不移除
page_t get_top_page()
{
    // 栈空
    if (pageStack.topIdx == 0)
    {
        //返回失败
        return 0;
    }
    // 打印并返回栈
    return pageStack.Data[pageStack.topIdx - 1];
}
///////////////////////////////////////////////////////////////////

// 关闭消息框
static void msg_event_cb(lv_event_t *e)
{
    lv_event_code_t code = lv_event_get_code(e);
    if (code == LV_EVENT_KEY)
    {
        lv_obj_t *obj = lv_event_get_current_target(e);
        if (obj == msgboxPage.page)
        {
            lv_msgbox_close(msgboxPage.page);
            msgboxPage.page = 0;
            page_show_pre();
        }
    }
}

void lv_thread()
{
    lv_task_handler();
    lv_tick_inc(5);
    vTaskDelay(5 / portTICK_RATE_MS);
}
void msgbox_quit()
{
    ESP_LOGI(TAG, "msgbox quit");
    if (msgboxPage.page)
    {
        lv_msgbox_close(msgboxPage.page);
        msgboxPage.page = 0;
    }
    if (get_top_page() == &waitPage)
    {
        pop_page();
    }
}
static const char *btns[] = {"Close", ""};
void show_smart_config_ok()
{

    msgboxPage.page = lv_msgbox_create(NULL, "Smart Config", "Successful!", btns, false);
    lv_obj_add_event_cb(msgboxPage.page, msg_event_cb, LV_EVENT_KEY, NULL);
    lv_group_remove_all_objs(group);

    lv_obj_center(msgboxPage.page);
    msgboxPage.quit = msgbox_quit;
    push_page(&msgboxPage);
    lv_group_add_obj(group, lv_msgbox_get_btns(msgboxPage.page));
    ESP_LOGI(TAG, "show smart OK");
}
void show_smart_config_fail()
{
    msgboxPage.page = lv_msgbox_create(NULL, "Smart Config", "Failed!", btns, false);
    lv_obj_add_event_cb(msgboxPage.page, msg_event_cb, LV_EVENT_KEY, NULL);
    lv_group_remove_all_objs(group);
    lv_group_add_obj(group, lv_msgbox_get_btns(msgboxPage.page));
    lv_obj_center(msgboxPage.page);
    msgboxPage.quit = msgbox_quit;
    push_page(&msgboxPage);
}

void show_smart_config_wait()
{
    btn_smart_config_start();
    lv_group_remove_all_objs(group);
    lv_scr_load(waitPage.page);
    push_page(&waitPage);
}
void page_init()
{
    lv_init();
    lv_port_disp_init();
    group = lv_group_create();
    lv_indev_set_group(lv_port_indev_init(), group);
    waitPage.page = lv_obj_create(0);
    spinner = lv_spinner_create(waitPage.page, 1000, 60);
    lv_obj_set_size(spinner, 100, 100);
    label2 = lv_label_create(waitPage.page);
    lv_label_set_long_mode(label2, LV_LABEL_LONG_SCROLL_CIRCULAR);     /*Circular scroll*/
    lv_obj_set_width(label2, 320);
    lv_label_set_recolor(label2, true);                      /*Enable re-coloring by commands in the text*/
    lv_label_set_text(label2, "wating for connect...");
    lv_obj_align(label2, LV_ALIGN_TOP_MID, 0, 0);
    lv_obj_set_style_text_align(label2, LV_TEXT_ALIGN_CENTER, 0);
    lv_obj_center(spinner);
    main_page_init();
    page_led_init();
    page_weather_init();
    waitPage.show = show_smart_config_wait;
    page_mp3_init();
    calendar_init();
}
void page_show_pre()
{
    ESP_LOGI(TAG, "show pre");
    page_t x = pop_page();
    if (x && x->quit)
    {
        x->quit();
    }
    x = pop_page();
    if (x && x->show)
    {
        x->show();
    }
    if (!x)
    {
        mainPage.show();
    }
}
//////////////////////////////////////////////////////////////////////////

